/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package grex.Conformal;

import grex.Data.Prediction;
import grex.Data.PredictionContainer;
import grex.Environment;
import grex.WekaModels.GrexLinearRegression;
import grex.WekaModels.GrexM5PBag;
import grex.WekaModels.WekaPredictiveModel;
import java.util.ArrayList;

/**
 *
 * @author RIK
 */
public class ConformalExpSAE implements IConformalMetric {
        private double beta = 0;
        @Override
        public double calcAlpha(Prediction prediction, double realValue) {
            PredictionContainer pc = new PredictionContainer(1);
            Prediction p = new Prediction(prediction);
            pc.put(p.getInstance(), p);
            model.execute(pc);
            double AE = Math.abs(prediction.getPrediction() - realValue);
            double predAE = Math.exp(p.getPrediction());
            double u=predAE+beta;
            if(u<0.0001)
                u=0.0001;
            
            AE=Math.abs(AE/(u));
            return AE;
        }

        @Override
        public ArrayList<Double> calcPredictionSet(Prediction prediction, double pAlpha) {
            ArrayList<Double> intervall = new ArrayList<>(2);
            PredictionContainer pc = new PredictionContainer(1);
            Prediction p = new Prediction(prediction);
            pc.put(p.getInstance(), p);
            model.execute(pc);
            double predAE = Math.exp(p.getPrediction());
            intervall.add(prediction.getPrediction() - pAlpha * (predAE+beta));
            intervall.add(prediction.getPrediction() + pAlpha * (predAE+beta));
            
            System.out.println("Pred: " + prediction.getPrediction() + " Real " + prediction.getTargetValue() + " predAE: " + predAE + " realAE " + (prediction.getPrediction()-prediction.getTargetValue()));
            return intervall;
        }
        
        WekaPredictiveModel model;
        @Override
        public void initICPModel(Environment env, PredictionContainer pcTrain) {
            model = new GrexM5PBag(env);
         //   model = new GrexLinearRegression(env);
            
            PredictionContainer pcAE = new PredictionContainer(pcTrain.size());
            for (Prediction p : pcTrain.values()) {
                Prediction newP = new Prediction(p);                
                double ae = Math.abs(p.getPrediction() - p.getTargetValue());
                if(ae<0.0001)
                    ae=0.0001;
                newP.setTargetValue(Math.log(ae));
                pcAE.put(p.getInstance(), newP);
            }
            model.train(pcAE);
            model.execute(pcAE);
           /* System.out.println("\nAEPrediction");
            for (Prediction p : pcAE.values()) {
                System.out.println("pred:" + p.getPrediction() + " Real:" + p.getTargetValue());
            }*/
        }
    }
